package org.fuzz.ibwrapper;

import java.awt.Button;
import java.util.LinkedHashSet;
import java.util.LinkedList;

import org.fuzz.ibwrapper.interfaces.IIBConnectionListener;

import com.ib.client.EClientSocket;

/**
 * Utility class to handle the connection to IB via the API.
 * @author Nate
 *
 */
public class FuzzIBConnection {
	
	/** private singleton instance*/
	private static FuzzIBConnection _instance = new FuzzIBConnection();
	
	private FuzzIBFeed mWrapper;
	private EClientSocket mSocket;
	
	/** client ID, IB specific */
	private static final int CLIENT_ID = 0;
	
	private LinkedHashSet<IIBConnectionListener> mConnectionListeners;
	
	private String sHost = null;
	private int iPort = 7496;
	
	private FuzzIBConnection(){
		mConnectionListeners = new LinkedHashSet<IIBConnectionListener>();
		mWrapper = new FuzzIBFeed();
		mSocket = new EClientSocket(mWrapper);
	}
	
	/**
	 * Obtain the singleton instance of this <code>FuzzIBConnection</code>
	 * @return
	 * 			the instance of the <code>FuzzIBConnection</code>
	 */
	public static FuzzIBConnection getInstance(){
		return _instance;
	}
	
	/**
	 * Connect with default host and port.
	 */
	public void connect(){
		connect(null, 7946);
	}
	
	/**
	 * Connect with specified host name and port. For a local host use <code>127.0.0.1</code>.
	 * The default port for the IB API is <code>7946</code>.
	 * 
	 * @param host
	 * @param port
	 */
	public void connect(String host, int port){
		if (mSocket.isConnected())
			return;
		
		sHost = host;
		iPort = port;
		
		mSocket.eConnect(sHost, iPort, CLIENT_ID);
		for (IIBConnectionListener listener : mConnectionListeners){
			listener.gainedConnection();
		}
	}
	
	/**
	 * Disconnect from the IB API.
	 */
	public void disconnect(){
		if (!mSocket.isConnected())
			return;
		
		mSocket.eDisconnect();
		for (IIBConnectionListener listener : mConnectionListeners){
			listener.lostConnection();
		}
	}
	
	/**
	 * Add a connection status listener to this Connection Manager.
	 * @param listener
	 */
	public void addConnectionListener(IIBConnectionListener listener){
		mConnectionListeners.add(listener);
	}
	/**
	 * Remove the specified IIBConnectionListener from this FuzzIBConnection.
	 * @param listener
	 */
	public void removeConnectionListener(IIBConnectionListener listener){
		mConnectionListeners.remove(listener);
	}

}
